/***************************************************************************/
/* NOTE:                                                                   */
/* This document is copyright (c) by Oz Solomonovich.  All non-commercial  */
/* use is allowed, as long as this document not altered in any way, and    */
/* due credit is given.                                                    */
/***************************************************************************/

#include "stdafx.h"
#include "ShellTools.h"


/////////////////////////////////////////////////////////////////////////////
// CInitializer 
// private class used for automatic initialization and cleanup of local 
// variables

//##ModelId=431C34D30203
static class CInitializer
{
public:
	//##ModelId=431C34D30222
    CInitializer();
	//##ModelId=431C34D30223
    ~CInitializer();

	//##ModelId=431C34D30233
    static LPSHELLFOLDER   m_sfDesktop;
	//##ModelId=431C34D30243
    static LPMALLOC        m_pAllocator;
	//##ModelId=431C34D30252
    static HIMAGELIST      m_hShellImageList;
} __init;

//##ModelId=431C34D30233
LPSHELLFOLDER CInitializer::m_sfDesktop  = NULL;
//##ModelId=431C34D30243
LPMALLOC      CInitializer::m_pAllocator = NULL;
//##ModelId=431C34D30252
HIMAGELIST    CInitializer::m_hShellImageList = NULL;

//##ModelId=431C34D30222
CInitializer::CInitializer()
{
    SHGetDesktopFolder(&m_sfDesktop);
    SHGetMalloc(&m_pAllocator);

    SHFILEINFO  sfi;
    m_hShellImageList = (HIMAGELIST)SHGetFileInfo((LPCSTR)"C:\\", 0, 
        &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
}


//##ModelId=431C34D30223
CInitializer::~CInitializer()
{
    m_sfDesktop->Release();
    m_pAllocator->Release();
}


                        // == Icon Extraction == //

//##ModelId=431C34D30271
typedef struct
{
    RECEIVERFUNC pReceiver;
    LPVOID       pContext;
    LPCTSTR      pszPath;
    UINT         uFlags;
} gfi_thread_data, *pgfi_thread_data;

static UINT gfiExecutor(LPVOID pParam)
{
    pgfi_thread_data pData = (pgfi_thread_data)pParam;

    HICON theIcon = GetFileIcon(pData->pszPath, pData->uFlags);

    pData->pReceiver(theIcon, pData->pContext);
    delete pData;

    return 0;
}

// GetFileIcon - returns the icon associated with a namespace object.
HICON GetFileIcon(LPCTSTR pszPath, UINT uFlags, RECEIVERFUNC pReceiver, 
                  LPVOID pContext)
{
    if (pReceiver == NULL)
    {
        SHFILEINFO  sfi;

        SHGetFileInfo(pszPath, 0, &sfi, sizeof(SHFILEINFO),
            uFlags | SHGFI_ATTRIBUTES | SHGFI_DISPLAYNAME | SHGFI_ICON | 
            SHGFI_SMALLICON);

        return ImageList_GetIcon(CInitializer::m_hShellImageList, 
            sfi.iIcon, 0);
    }
    else
    {
        pgfi_thread_data pData = new gfi_thread_data;
        pData->pReceiver = pReceiver;
        pData->pContext  = pContext;
        pData->pszPath   = pszPath;
        pData->uFlags    = uFlags;

        return (HICON)AfxBeginThread(gfiExecutor, pData);
    }
}


                          // == Open Folder == //

void OpenLocation(CString &cLocation, OpenMethods aMethod)
{
    if (aMethod == defaultAction)
    {
        ShellExecute(AfxGetMainWnd()->m_hWnd, NULL, cLocation, NULL, NULL, 
            SW_SHOWDEFAULT);
    }
    else
    {
        CString             cExecString = "", cWinDir;
        PROCESS_INFORMATION pi;
        STARTUPINFO         si;

        switch (aMethod)
        {
            case explore:
                cExecString += "/e,";
                break;
            
            case exploreFrom:
                cExecString = "/e,/root,";
                break;
        }
        
        GetStartupInfo(&si);
        GetWindowsDirectory(cWinDir.GetBuffer(256), 256);
        cWinDir.ReleaseBuffer();
        cExecString = cWinDir + "\\Explorer.exe " + cExecString + cLocation;

        CreateProcess(NULL, (char *)(const char *)(cExecString),  NULL,
            NULL, FALSE, 0, NULL, NULL, &si, &pi);
    }
    
}

